package product

import (
	"fmt"
	"woo-server/coms/structs"
	"woo-server/coms/utils"
	"woo-server/models/db"
)

// 商品分类字段表
type ProductCategory struct {
	*structs.Common `gorm:"-" json:"-"`
	CategoryId      uint64      `gorm:"primary_key;AUTO_INCREMENT;column:category_id;"` // 自增主键
	ParentId        uint64      `gorm:"column:parent_id;size:255;"`                     // 上级分类id
	Name            string      `gorm:"column:name;size:255;"`                          // 分类名称
	ImageId         uint        `gorm:"column:image_id;size:255;"`                      // 分类图片id
	Sort            uint        `gorm:"column:sort;size:255;"`                          // 排序方式(数字越小越靠前)
	ChildRen        interface{} // 子集
	Select          []uint64    // 选中后的数组值(前端用)
	db.Basics
}

// 表名
func (m *ProductCategory) TableName() string {
	return "woo_product_category"
}

func (m *ProductCategory) GetConfig() structs.CFConfig {
	list := structs.CFConfig{}
	list.Column = m.Column()
	list.Forms = m.Forms()
	return list
}

func (m *ProductCategory) Column() []structs.ColumnCommon {
	result := make([]structs.ColumnCommon, 0)
	result = append(result, structs.ColumnCommon{Title: "ID", DataIndex: "CategoryId"})
	result = append(result, structs.ColumnCommon{Title: "名称", DataIndex: "Name"})
	result = append(result, structs.ColumnCommon{Title: "排序", DataIndex: "Sort"})
	result = append(result, structs.ColumnCommon{Title: "创建时间", DataIndex: "UpdateDate"})
	result = append(result, structs.ColumnCommon{Title: "操作", DataIndex: "Operation"})
	return result
}

func (m *ProductCategory) Forms() []structs.FormsCommon {
	result := make([]structs.FormsCommon, 0)
	var option structs.Options
	var options []structs.Options
	option.Value = 0
	option.Label = "顶级栏目"
	options = append(options, option)
	_, list := m.GetAllCategory()
	options = MergeSlice(options, m.SetOption(list, 0))
	result = append(result, structs.FormsCommon{Key: "CategoryId", Label: "主键ID", Type: "primary_key", Options: []string{}})
	result = append(result, structs.FormsCommon{Key: "ParentId", Label: "上级分类", Type: "OnceSelect", Options: options})
	result = append(result, structs.FormsCommon{Key: "ImageId", Label: "图片", Type: "OnlyUploadImage", Options: []string{}})
	result = append(result, structs.FormsCommon{Key: "Name", Label: "分类名称", Type: "input", Options: []string{}})
	result = append(result, structs.FormsCommon{Key: "Sort", Label: "排序", Type: "number", Options: []string{}})
	return result
}

// 合并数组
func MergeSlice(s1 []structs.Options, s2 []structs.Options) []structs.Options {
	slice := make([]structs.Options, len(s1)+len(s2))
	copy(slice, s1)
	copy(slice[len(s1):], s2)
	return slice
}

// 初始化
func NewProductCategory(com *structs.Common) *ProductCategory {
	d := &ProductCategory{}
	return d
}

// 创建
func (m *ProductCategory) Create() error {
	return utils.GORM.Debug().Table(m.TableName()).Create(m).Error
}

// 批量创建
func (m *ProductCategory) BatchCreate(data []*ProductCategory) error {
	return utils.GORM.Debug().Table(m.TableName()).Create(data).Error
}

// 获取分页列表及总数
func (m *ProductCategory) GetUserListAndTotal(search string, page int, pageSize int) ([]*ProductCategory, int64) {
	list := make([]*ProductCategory, 0)
	var total int64 = 0

	// 查询
	query := utils.GORM.Debug().Table(m.TableName())
	query = query.Order("sort asc")
	if len(search) > 0 {
		search = fmt.Sprintf("%%%s%%", search)
		query = query.Where("name like ? or no like ? or email like ?", search, search, search)
	}

	// 总数
	query.Count(&total)

	// 列表
	offset := (page - 1) * pageSize
	query.Limit(pageSize).Offset(offset).Find(&list)

	return list, total
}

// 获取所有商品分类(分页)
// return treeList 树状商品分类 , list 非树状
func (m *ProductCategory) GetListAndTotal(search string, page int, pageSize int) ([]structs.ProductCategory, int64) {
	list := make([]structs.ProductCategory, 0)
	list2 := make([]structs.ProductCategory, 0)
	var total int64 = 0
	// 查询
	query := utils.GORM.Debug().Table(m.TableName())
	query = query.Order("sort asc")

	// 分页查询
	query = query.Where("parent_id != 0")
	// 列表
	query.Find(&list)

	// 重新实例化
	query = utils.GORM.Debug().Table(m.TableName())
	query = query.Order("sort asc")
	// 列表
	offset := (page - 1) * pageSize
	if len(search) > 0 {
		search = fmt.Sprintf("%%%s%%", search)
		query = query.Where("name like ?", search)
	}

	// 分页查询
	query = query.Where("parent_id = 0")

	// 总数
	query.Count(&total)

	query.Limit(pageSize).Offset(offset).Find(&list2)

	fmt.Println("[page] menus :", list2)
	treeList := MakeList(list, list2, 0, []uint64{})
	return treeList, total
}

// 获取所有商品分类
// @param isHidden 是否显示
// return treeList 树状商品分类 , list 非树状
func (m *ProductCategory) GetAllCategory() ([]structs.ProductCategory, []structs.ProductCategory) {
	list := make([]structs.ProductCategory, 0)
	// 查询
	query := utils.GORM.Debug().Table(m.TableName())
	query = query.Order("sort asc")

	// 列表
	query.Find(&list)
	//fmt.Println("all menus :", list)
	treeList := MakeList(list, list, 0, []uint64{})
	return treeList, list
}

// 获取单数据
func (m *ProductCategory) GetFirst(where string, field int) *ProductCategory {
	//info := make([]*ProductCategory, 0)

	// 查询
	query := utils.GORM.Debug().Table(m.TableName())

	query = query.Where(where, field)

	// 总数
	//query.Count(&total)

	// 列表
	//offset := (page - 1) * pageSize
	query.First(&m)
	return m
}

// 更新商品分类
func (m *ProductCategory) Save() error {
	// 更新
	return utils.GORM.Debug().Table(m.TableName()).Save(m).Error
}

// 删除商品分类
func (m *ProductCategory) Delete() error {
	return utils.GORM.Debug().Table(m.TableName()).Delete(m).Error
}

// 获取单条数据
func (m *ProductCategory) First() error {
	return utils.GORM.Debug().Table(m.TableName()).First(m).Error
}

func (m *ProductCategory) SetOption(data []structs.ProductCategory, pid uint64) []structs.Options {
	var List []structs.Options
	for _, v := range data {
		if v.ParentId == pid {
			//fmt.Println(pid)
			var option structs.Options
			option.Value = v.CategoryId
			option.Label = v.Name
			option.ChildRen = m.SetOption(data, v.CategoryId)
			//fmt.Println(option)
			List = append(List, option)
		}
	}
	return List
}

/**
递归多级商品分类
@param RoleMenu []ProductCategory 要遍历商品分类
@param pid uint64 父ID
@param showHidden bool 是否显示隐藏商品分类
@param Select []uint64 当前父子ID关联数组
return []ProductCategory
*/
func MakeList(data []structs.ProductCategory, data2 []structs.ProductCategory, pid uint64, Select []uint64) []structs.ProductCategory {
	var List []structs.ProductCategory
	for _, v := range data2 {
		if v.ParentId == pid {
			//fmt.Println(pid)
			var option structs.ProductCategory
			option.CategoryId = v.CategoryId
			option.Name = v.Name
			option.ParentId = v.ParentId
			option.Sort = v.Sort
			option.ImageId = v.ImageId
			option.CreateDate = v.CreateDate
			option.UpdateDate = v.UpdateDate
			NewSelect := Select
			if v.ParentId == 0 {
				NewSelect = []uint64{0}
			} else {

				if NewSelect[0] != 0 {
					NewSelect = append(NewSelect, v.ParentId)
				} else {
					NewSelect = []uint64{v.ParentId}
				}
			}
			option.Select = NewSelect
			option.ChildRen = MakeList(data, data, v.CategoryId, NewSelect)
			List = append(List, option)
		}
	}
	return List
}
